package com.yunhe.device.repository.authority;

import com.yunhe.common.model.authority.ResourceTree;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 单位数据仓库
 * @desc 单位数据仓库定义
 * @author liuronglei
 */
@Repository
public interface ResourceTreeRepository extends Neo4jRepository<ResourceTree, Long> {
    /**
     * 根据单位ID获得绑定资源
     * @param firmId 单位ID
     */
    @Query("match(f:Firm)-[r:HAS_RESOURCE]->(res) where ID(f)={firmId} return"
            + " ID(res) as id, res.code as code, r.type as type,not exists((res)-[:CONTAINS]->()) as leaf, res as object")
    Iterable<ResourceTree> getResourceByFirmId(@Param("firmId") Long firmId);

    /**
     * 根据单位ID获得绑定资源
     * @param stationId 电站ID
     */
    @Query("match(f:Station)-[r:HAS_RESOURCE]->(res) where ID(f)={stationId} return"
            + " ID(res) as id, res.code as code, r.type as type,not exists((res)-[:CONTAINS]->()) as leaf, res as object")
    Iterable<ResourceTree> getResourceByStationId(@Param("stationId") Long stationId);

    /**
     * 根据单位ID和类型获得绑定资源
     * @param firmId 单位ID
     * @param typeList 类型列表
     */
    @Query("match(f:Firm)-[r:HAS_RESOURCE]->(res) where ID(f)={firmId} and r.type in {typeList} return"
            + " ID(res) as id, res.code as code,r.type as type,not exists((res)-[:CONTAINS]->()) as leaf, res as object")
    Iterable<ResourceTree> getResourceByFirmIdAndType(@Param("firmId") Long firmId, @Param("typeList") List<String> typeList);

    /**
     * 根据单位ID和类型获得绑定资源
     * @param stationId 单位ID
     * @param typeList 类型列表
     */
    @Query("match(f:Station)-[r:HAS_RESOURCE]->(res) where ID(f)={stationId} and r.type in {typeList} return"
            + " ID(res) as id, res.code as code,r.type as type,not exists((res)-[:CONTAINS]->()) as leaf, res as object")
    Iterable<ResourceTree> getResourceByStationIdAndType(@Param("stationId") Long stationId, @Param("typeList") List<String> typeList);

    /**
     * 根据单位ID查找单位下的电站绑定的设备
     * @param firmId 单位ID
     */
    @Query("match(n:Firm)-[:HAS_STATION]->(s:Station)-[r:HAS_RESOURCE]->(res) where ID(n)={firmId} return " +
            "ID(res) as id, res.code as code, r.type as type,not exists((res)-[:CONTAINS]->()) as leaf, res as object")
    Iterable<ResourceTree> getResourceIsBindStationByFirm(@Param("firmId") Long firmId);

    /**
     * 绑定单位与资源的关系
     * @param firmId 单位ID
     * @param type 类型
     * @param resourceId 资源ID
     */
    @Query("start firm=node({firmId}),resource=node({resourceId}) create (firm)-[:HAS_RESOURCE{type:{type}}]->(resource)")
    void bindResource(@Param("firmId") Long firmId, @Param("type") String type, @Param("resourceId") Long resourceId);

    /**
     * 根据单位代码绑定单位与资源的关系
     * @param firmCode 单位代码
     * @param type 类型
     * @param resourceId 资源ID
     */
    @Query("start resource=node({resourceId}) match(firm:Firm{code:{firmCode}}) create (firm)-[:HAS_RESOURCE{type:{type}}]->(resource)")
    void bindResourceByFirmCode(@Param("firmCode") Long firmCode, @Param("type") String type, @Param("resourceId") Long resourceId);

    /**
     * 解绑单位与资源的关系
     * @param firmId 单位ID
     * @param resourceId 资源ID
     */
    @Query("start firm=node({firmId}),resource=node({resourceId}) match(firm)-[r:HAS_RESOURCE]->(resource) delete r")
    void unbindResource(@Param("firmId") Long firmId, @Param("resourceId") Long resourceId);

    /**
     * 解绑单位与所有资源的关系
     * @param firmId 单位ID
     */
    @Query("start firm=node({firmId}) match(firm)-[r:HAS_RESOURCE]->() delete r")
    void unbindAllResources(@Param("firmId") Long firmId);

    @Query("match(rt:RealStation)-[r:BELONG_TO_STATION]->(station:Station) where ID(rt)={id} return station.projectNo")
    String findProjectByRealStationId(@Param("id") Long ownedPark);
}